<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>

<body>
  <script>
    //禁止重复声明
    {
      var count = 30;
      let count = 30;
    }

    //不存在变量提升
    {
      // var 的情况
      console.log(foo); // 输出undefined
      var foo = 2;

      // let 的情况
      console.log(bar); // 报错ReferenceError
      let bar = 2;
    }

    //暂时性死区
    var tmp = 123;

    if (true) {
      tmp = 'abc'; // ReferenceError
      let tmp;
    }
        //上面代码中，存在全局变量tmp，但是块级作用域内let又声明了一个局部变量tmp，导致后者绑定这个块级作用域，所以在let声明变量前，对tmp赋值会报错。

        //ES6 明确规定，如果区块中存在let和const命令，这个区块对这些命令声明的变量，从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量，就会报错。

        //总之，在代码块内，使用let命令声明变量之前，该变量都是不可用的。这在语法上，称为“暂时性死区”（temporal dead zone，简称 TDZ）。typeof 也会报错


    //let 块作用域，若let改成var 输出结果又是怎样的？支持ES6的话，推荐使用let
    function f1() {
      let n = 5;
      if (true) {
        let n = 10;
      }
      console.log(n); // 5
    }
    f1()
  </script>
</body>

</html>